Intro, a lyrics-melody data frame
library(tidyverse)
beluga_song <- ggdoremi:::join_phrases_drm_lyrics()
## Joining with `by = join_by(drm)`
## Joining with `by = join_by(id_phrase, id_in_phrase)`
beluga_song %>% head()
## # A tibble: 6 × 6
## # Groups: id_phrase [1]
## id_phrase id_in_phrase drm doremi freq lyric
## <int> <int> <fct> <fct> <dbl> <chr>
## 1 1 1 m mi 557. Ba
## 2 1 2 m mi 557. by
## 3 1 3 r re 495 Be
## 4 1 4 d do 440 lu
## 5 1 5 S sol 330 ga
## 6 1 6 d do 440 in
Dandalion song w/o extension
compute_panel_dandalion <- function(data, scales){
spacer_df <- tibble(spacer = 1)
data <- bind_rows(spacer_df, data, spacer_df)
data$id <- 1:nrow(data)
# nrow(data)
data$around <- 1:(nrow(data))/nrow(data)
data$circ_angle <- -data$around*2*pi -
pi/2 + 2*pi/nrow(data)/2
data$x <- data$radius * cos(data$circ_angle)
data$xend <- 0
data$yend <- 0
data$y <- data$radius * sin(data$circ_angle)
data$angle <- -data$around*360 + 180
data %>%
slice(-1) %>%
slice(-nrow(.))
}
ggdoremi:::join_phrases_drm_lyrics() %>%
# head(30) %>%
mutate(radius = as.numeric(drm) + 10) %>%
compute_panel_dandalion() %>%
ggplot() +
ggstamp::stamp_circle(radius = 8+10, alpha = 0, size = .25, linetype = "dotted") +
ggstamp::stamp_circle(radius = 8+12, alpha = 0, size = .25, linetype = "dotted") +
ggstamp::stamp_circle(radius = 8+14, alpha = 0, size = .25, linetype = "dotted") +
aes(x = x, radius = radius, y = y, label = lyric, angle = angle) +
geom_segment(xend = 0, yend = 0, color = "black", linewidth = .5) +
geom_point(shape = 21, size = 16, fill = "white") +
# aes(color = doremi) +
geom_text() +
coord_equal() +
theme_void()
## Joining with `by = join_by(drm)`
## Joining with `by = join_by(id_phrase, id_in_phrase)`
## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_segment()`).
## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_point()`).
## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_text()`).

statexpress enabled extension
write extension
stat_dandalion <- function(geom = "segment", ...){
statexpress::stat_panel(compute_panel_dandalion, geom, ...)
}
geom_dandalion_segment <- stat_dandalion
geom_dandalion_text <- function(...){stat_dandalion(geom = "text", ...)}
geom_dandalion_point <- function(...){stat_dandalion(geom = "point", ...)}
stamp_staff_dms <- function(radius_addition = 10 ){
list(
ggstamp::stamp_circle(radius = 8+0+radius_addition, alpha = 0, size = .25, linetype = "dotted"),
ggstamp::stamp_circle(radius = 8+2+radius_addition, alpha = 0, size = .25, linetype = "dotted"),
ggstamp::stamp_circle(radius = 8+4+radius_addition, alpha = 0, size = .25, linetype = "dotted")
)
}
stamp_staff_dmst <- function(radius_addition = 10 ){
list(stamp_staff_dms(radius_addition = radius_addition),
ggstamp::stamp_circle(radius = 8+6+radius_addition,
alpha = 0, size = .25,
linetype = "dotted")
)
}
stamp_staff_dmstr <- function(radius_addition = 10 ){
list(stamp_staff_dmst(radius_addition = radius_addition),
ggstamp::stamp_circle(radius = 8+8+radius_addition,
alpha = 0, size = .25,
linetype = "dotted")
)
}
Use extension
ggdoremi:::join_phrases_drm_lyrics() ->
beluga_song
## Joining with `by = join_by(drm)`
## Joining with `by = join_by(id_phrase, id_in_phrase)`
head(beluga_song)
## # A tibble: 6 × 6
## # Groups: id_phrase [1]
## id_phrase id_in_phrase drm doremi freq lyric
## <int> <int> <fct> <fct> <dbl> <chr>
## 1 1 1 m mi 557. Ba
## 2 1 2 m mi 557. by
## 3 1 3 r re 495 Be
## 4 1 4 d do 440 lu
## 5 1 5 S sol 330 ga
## 6 1 6 d do 440 in
beluga_song %>%
ggplot() +
aes(radius = as.numeric(drm)) +
geom_dandalion_segment() +
geom_dandalion_point(size = 16,
shape = 21,
fill = "white") +
aes(label = lyric) +
geom_dandalion_text() +
coord_equal()
## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_segment()`).
## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_point()`).
## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_text()`).

Another example
lyrics_abc <- "a b c d e f g
h i j k l m n o p
q r s t u v
w x y z
Now I know my A B Cs
Next time won't you sing with me"
drm_abc <- "ddsslls
ffmmrrrrd
ssfmmr
sfmr
ddsslls
ffmmrrd"
ggdoremi:::join_phrases_drm_lyrics(drm_abc,
lyrics_phrases =
lyrics_abc %>% str_to_title()) %>%
ggplot() +
aes(radius = as.numeric(drm) + 3) +
stamp_staff_dms(3) +
geom_dandalion_segment(color = "black",
size = .5) +
geom_dandalion_point(size = 10,
fill = "white",
shape = 21) +
aes(label = lyric) +
geom_dandalion_text() +
coord_equal() +
theme_void() +
aes(size = 5)
## Joining with `by = join_by(drm)`
## Joining with `by = join_by(id_phrase, id_in_phrase)`
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

last_plot() %+%
(ggdoremi:::join_phrases_drm_lyrics(drm_abc,
lyrics_abc)[1:26,]) +
aes(size = 7) +
guides("none")
## Joining with `by = join_by(drm)`
## Joining with `by = join_by(id_phrase, id_in_phrase)`
## Warning: Guides provided to `guides()` must be named.
## ℹ All guides are unnamed.

lyrics_doe_a_deer <-
'Doe a deer a fe-male deer
ray a drop of gol-den sun
me a name I call my-self
far a long long way to run
sew a need-le pull-ing thread
la a note to fol-low sol
tea a drink with jam and bread
that will bring us back to do o o o'
drm_doe_a_deer <-
'drmrmrm
rmffmrf
mfsmsms
fsllsfl
sdrmfsl
lrmfslt
tmfslt1
1tlsts1smr'
ggdoremi:::join_phrases_drm_lyrics(drm_doe_a_deer, lyrics_phrases = lyrics_doe_a_deer) %>%
# head(30) %>%
ggplot() +
stamp_staff_dmst(0) +
aes(radius = as.numeric(drm) ) +
geom_dandalion_segment(xend = 0, yend = 0) +
geom_dandalion_point(shape = 21, size = 19, fill = "white") +
aes(color = doremi, label = lyric) +
geom_dandalion_text(size = 7) +
coord_equal() +
theme_void() +
guides(color = "none", label = "none")
## Joining with `by = join_by(drm)`
## Joining with `by = join_by(id_phrase, id_in_phrase)`

last_plot() +
aes(label = doremi)
